package com.winit.requirement.manager;

import com.alibaba.fastjson.JSONObject;
import com.winit.base.configModel.ProjectPlanCodeProjects;
import com.winit.common.CloudLinkSend.MqMsgType;
import com.winit.common.CloudLinkSend.MsgSend;
import com.winit.common.base.bean.ExecuteResult;
import com.winit.common.base.bean.Status;
import com.winit.common.base.web.BaseController;
import com.winit.common.util.DateGenerator;
import com.winit.common.util.TableIdUtil;
import com.winit.commons.util.*;
import com.winit.config.model.Config;
import com.winit.config.service.IConfigService;
import com.winit.feature.manager.FeatureManager;
import com.winit.flow.service.IFlowService;
import com.winit.indexing.model.Indexing;
import com.winit.indexing.model.IndexingId;
import com.winit.indexing.service.IIdexingService;
import com.winit.issue.service.IIssueService;
import com.winit.projectPlan.model.ProjectPlan;
import com.winit.projectPlan.service.IProjectPlanService;
import com.winit.requirement.model.*;
import com.winit.requirement.repository.BrdRequirementRepository;
import com.winit.requirement.repository.BrdRequirementRepositoryOperation;
import com.winit.requirement.repository.ReqFeatureRepository;
import com.winit.requirement.repository.ReqHistoryRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Component
public class BrdRequirementManager {

    private static Logger log = LoggerFactory.getLogger(BrdRequirementManager.class);

    @Value("${beetle_auth_url}")
    private String BEETLE_AUTH_URL;

    @Autowired
    private BrdRequirementRepository brdRequirementRepository;

    @Autowired
    private BrdRequirementRepositoryOperation requirementRepositoryOperation;
    @Autowired
    private FeatureManager featureManager;
    @Autowired
    private IIdexingService indexingService;
    @Autowired
    private ReqFeatureRepository reqFeatureRepository;
    @Autowired
    private ReqHistoryRepository reqHistoryRepository;

    @Autowired
    private IIssueService issueService;
    @Autowired
    private ProjectPlanCodeProjects projectPlanCodeProjects;
    @Autowired
    private IProjectPlanService projectPlanService;
    @Autowired
    private IFlowService flowService;
    @Autowired
    private MsgSend msgSend;

    @Autowired
    private IConfigService configService;


    public List<?> getBrdRequirements(String brdId, String projectPlanId, String reqId, String productLineId, String status, String chargerAccount, String keyword, boolean withFeatureDesc,Long startDate,Boolean isOnline) {
        String excludeIsDel = "0";
        String sDate=null;
        String online=null;
        if(null!=startDate){
             sDate = DateGenerator.getYYYY_MM_DD(startDate);
        }
        if(reqId!=null || (isOnline!=null && isOnline)){
            online="1";
        }
        List<BrdRequirement> brdRequirements = this.requirementRepositoryOperation.getBrdRequirements(brdId, projectPlanId, reqId, productLineId, status, chargerAccount, keyword, excludeIsDel,sDate,online);
        if (CollectionUtils.isEmpty(brdRequirements)) {
            return new ArrayList<>();
        }
        if (withFeatureDesc) {
            IndexingId indexingId = new IndexingId();
            indexingId.setIndexGroup("req_feature_indexing");
            for (BrdRequirement brdRequirement : brdRequirements) {
                indexingId.setFilterTag(brdRequirement.getReqId());
                Indexing indexing = this.indexingService.getIndexing(indexingId);
                if (indexing != null) {
                    brdRequirement.setFeatureNodes(indexing.getIndexMap());
                }
            }
        }
        return brdRequirements;
    }


    public ExecuteResult<BrdRequirement> saveBrdRequirement(BrdRequirement brdRequirement) {
        ExecuteResult<BrdRequirement> rs = new ExecuteResult<BrdRequirement>();
        /** brd_id为空，执行新增brdRequirement操作 */
        if (StringUtils.isEmpty(brdRequirement.getReqId())) {
            log.info("no req_id found, brd_requirement creation will be executed...");
            try {
                rs = this.createBrdRequirement(brdRequirement);
                rs.setData(brdRequirement);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                rs.setCode(BaseController.REQUEST_ERROR);
                rs.setDesc("sys err, create requirement failed");
            }

            return rs;
        }





        /** 否则，进行更新操作 */

        //删除操作
        if ("0".equals(brdRequirement.getReqIsDel())) {
            log.info("brd delete will be executed...brd_id:" + brdRequirement.getBrdId());
            rs = this.deleteBrdRequirement(brdRequirement);
            return rs;
        }

        //处理req feature desc
        Set<String> existsFeatureIds = brdRequirement.getFeatureNodes() == null ? null : brdRequirement.getFeatureNodes().keySet();
        Map<String, String> featureDescs = brdRequirement.getFeatureDesc();
        if (!CollectionUtils.isEmpty(featureDescs)) {
            Iterator<String> featureIds = featureDescs.keySet().iterator();
            ReqFeatureId reqFeatureId = new ReqFeatureId();
            reqFeatureId.setReqId(brdRequirement.getReqId());
            while (featureIds.hasNext()) {
                String temp = featureIds.next();
                if (null != existsFeatureIds) {
                    if (!existsFeatureIds.contains(temp)) {  //已经解除关联的feature desc不再处理
                        continue;
                    }
                }

                String desc = featureDescs.get(temp);

                if (StringUtils.isEmpty(desc)) {    //删除指定描述
                    reqFeatureId.setFeatureId(temp);
                    this.reqFeatureRepository.delete(reqFeatureId);
                } else {//这里会更新指定描述
                    reqFeatureId.setFeatureId(temp);
//                    ReqFeature exists = this.reqFeatureRepository.findOne(reqFeatureId);
                    ReqFeature exists = this.reqFeatureRepository.findByReqIdAndFeatureId(reqFeatureId.getReqId(), reqFeatureId.getFeatureId());
                    if (null != exists) {
                        this.reqFeatureRepository.updateReqFeatureDesc(brdRequirement.getReqId(), temp, desc);
                    } else {
                        ReqFeature reqFeature = new ReqFeature();
                        reqFeature.setReqId(brdRequirement.getReqId());
                        reqFeature.setFeatureId(temp);
                        reqFeature.setDesc(desc);
//                        this.reqFeatureRepository.save(reqFeature);
                        this.reqFeatureRepository.insertEntity(brdRequirement.getReqId(), temp, desc);
                    }
                }
            }
        }
        BrdRequirement dbBrdRequirement = this.brdRequirementRepository.findOne(brdRequirement.getReqId());
        if (null == dbBrdRequirement){
            return rs;
        }
        //要清除req关联的project_plan，需要强制指定projectPlanId为null
        if ("null".equalsIgnoreCase(brdRequirement.getProjectPlanId())){
            if ((!StringUtils.isEmpty(dbBrdRequirement.getReqStatus())) && (!"COMPLETED".equalsIgnoreCase(dbBrdRequirement.getReqStatus()))) {
                brdRequirement.setReqStatus(Status.DISSOCIATION.name());
            }
        } else {
            if ((!StringUtils.isEmpty(brdRequirement.getProjectPlanId())) && (!"COMPLETED".equalsIgnoreCase(dbBrdRequirement.getReqStatus()))){
                brdRequirement.setReqStatus(Status.P_PLAN.name());
            }
        }
        int updateNum = this.requirementRepositoryOperation.updateBrdRequirementById(brdRequirement);
        if (null != brdRequirement.getIssues()) {
            this.refreshIssues(brdRequirement.getReqId(), brdRequirement.getIssues());
        }
        rs = new ExecuteResult<BrdRequirement>();
        rs.setData(brdRequirement);

        if (!StringUtils.isEmpty(dbBrdRequirement.getIssues()) && !StringUtils.isEmpty(dbBrdRequirement.getProjectPlanId())){
            this.sendNeedMsg(dbBrdRequirement.getReqId());
        }

        return rs;
    }

    private void sendNeedMsg(String reqId){
        Map map = new HashMap();
        List list = new ArrayList();
        list.add(reqId);
        map.put("reqIds", list);
        msgSend.sendMsg(MqMsgType.PROJECT,map);

    }


    private ExecuteResult createBrdRequirement(BrdRequirement brdRequirement) throws Exception {
        ExecuteResult rs = new ExecuteResult();
        String reqName = brdRequirement.getReqName();
        if ((!StringUtils.isEmpty(reqName)) && (!CollectionUtils.isEmpty(this.brdRequirementRepository.findByReqName(reqName)))) {
            rs.setCode(BaseController.REQUEST_ERROR);
            rs.setDesc("requirement name 不能重复");
            return rs;
        }

        if ("1".equals(brdRequirement.getNewPlan()) && (StringUtils.isEmpty(brdRequirement.getProjectFlag()) || StringUtils.isEmpty(brdRequirement.getTokenId()))) {
            rs.setCode(BaseController.REQUEST_ERROR);
            rs.setDesc("创建同名projectPlan时projectFlag, tokenId均不能为空");
            return rs;
        }


        //设置req_id
        brdRequirement.setReqId(TableIdUtil.createReqId());
        brdRequirement.setReqNo("REQ" + SeqGenerate.createSerialNo());
        /** 171221 deprecate */
//        rs = this.flushIndexing(brdRequirement);
//        if (!rs.success()) {
//            return rs;
//        }
        /**目前未使用 2018-01-10*/
        Map<String, String> featureDescs = brdRequirement.getFeatureDesc();
        if (!CollectionUtils.isEmpty(featureDescs)) {
            Iterator<String> iterator = featureDescs.keySet().iterator();
            List<ReqFeature> reqFeatures = new ArrayList<>();
            while (iterator.hasNext()) {
                ReqFeature temp = new ReqFeature();
//                ReqFeatureId reqFeatureId = new ReqFeatureId();
                temp.setReqId(brdRequirement.getReqId());
                String featureId = iterator.next();
                temp.setFeatureId(featureId);
//                temp.setId(reqFeatureId);
                temp.setDesc(featureDescs.get(featureId));
                reqFeatures.add(temp);
            }
            this.reqFeatureRepository.save(reqFeatures);
        }


        //设置状态为新建
        brdRequirement.setReqStatus(BrdRequirementStatus.NEW.name());
        //默认非删除状态
        brdRequirement.setReqIsDel("1");
        //创建时间(默认当前时间)
        if (null == brdRequirement.getReqCreateTime()) {
            brdRequirement.setReqCreateTime(DateUtil.getCurDate());
        }

        this.brdRequirementRepository.save(brdRequirement);
        if (null != brdRequirement.getIssues()) {
            this.refreshIssues(brdRequirement.getReqId(), brdRequirement.getIssues());
        }
        if ("1".equals(brdRequirement.getNewPlan())) {
            log.info("创建相同名称的项目计划");
            ProjectPlan projectPlan = new ProjectPlan();

            List<String> reqIds = new ArrayList<>();
            reqIds.add(brdRequirement.getReqId());
            projectPlan.setReqIds(reqIds);

            String projectCode = projectPlanCodeProjects.getProjectCode(brdRequirement.getProjectFlag());
            if (!StringUtils.isEmpty(projectCode)) {
                projectPlan.setProjectPlanCode(projectCode + DateUtil.getCurDateStr("yyyyMMddHHmm"));

                projectPlan.setProjectPlanName(brdRequirement.getReqName());
                projectPlan.setProjectPlanCreateTime(brdRequirement.getReqCreateTime());
                projectPlan.setProjectPlanCreaterAccount(brdRequirement.getReqCreaterAccount());
                projectPlan.setProjectPlanCreaterRealname(brdRequirement.getReqCreaterRealname());
                projectPlan.setProjectPlanChargerAccount(brdRequirement.getReqChargerAccount());
                projectPlan.setProjectPlanChargerRealname(brdRequirement.getReqChargerRealname());
                projectPlan.setProjectPlanStartupTime(DateGenerator.getNowDate());
                projectPlan.setProjectPlanOnlineTime(DateGenerator.getNextFriday());
                projectPlan.setProjectPlanDesc(brdRequirement.getReqDesc());
                projectPlan.setTokenId(brdRequirement.getTokenId());
                rs = this.projectPlanService.createProjectPlanForReq(projectPlan);
                if("0".equals(rs.getCode()) && !StringUtils.isEmpty(brdRequirement.getIssues())){
                    sendNeedMsg(brdRequirement.getReqId());
                }
            } else {
                String msg = "未找到project flag对应的project code配置， project plan creating将不会被执行";
                rs.setCode(BaseController.REQUEST_ERROR);
                rs.setDesc(msg);
                log.error("req已创建，但" + msg);
            }
        }
        return rs;
    }


    private void refreshIssues(String reqId, String issues) {
        if (null == issues) {
            return;
        }
        List<String> issueIds = StringUtils.isEmpty(issues) ? new ArrayList<String>() : Arrays.asList(issues.split(","));
        this.issueService.refreshIssueRelationForReq(reqId, issueIds);
    }

//    public static void main(String[]args){
//        System.out.println("".split(",").length);
//    }

    /**
     * 171221
     *
     * @param brdRequirement
     * @return
     * @deprecate 该方法：
     * 1、查出存在的indexing,与传入的brdRequirement中的map1进行对比，如果map1中包含的indexing中未存在的项，
     * 则判定该新增项是否能够新增（是否被其它req占用），若占用则判定失败返回；
     * 2、清空原有的indexing项（filter_group: req_feature_indexing、 feature_req_indexing），并根据map1新建indexing，若传入的map1为空，则不新建
     */
    private ExecuteResult flushIndexing(BrdRequirement brdRequirement) {
        ExecuteResult executeResult = new ExecuteResult();
        Map<String, String> newMap = brdRequirement.getFeatureNodes();

        Indexing indexing = new Indexing();
        IndexingId indexingId = new IndexingId();
        indexingId.setIndexGroup("req_feature_indexing");
        indexingId.setFilterTag(brdRequirement.getReqId());
        indexing.setId(indexingId);

        IndexingId indexingId1 = new IndexingId();
        indexingId1.setIndexGroup("feature_req_indexing");


        Indexing existIndexing = this.indexingService.getIndexing(indexingId);
        Map<String, String> existsMap = existIndexing == null ? null : existIndexing.getIndexMap();


        Map<String, String> removeIndexMap = new HashMap<>();

        Map<String, String> addIndexingMap = new HashMap<>();

        if (!CollectionUtils.isEmpty(newMap)) {
            addIndexingMap.putAll(newMap);
            if (!CollectionUtils.isEmpty(existsMap)) {  //生成addMap
                addIndexingMap.keySet().removeAll(existsMap.keySet());
            }
        }
        /** 校验是否被其它req占用 */
        if (!CollectionUtils.isEmpty(addIndexingMap)) {
            Iterator<String> iterator1 = addIndexingMap.keySet().iterator();
            while (iterator1.hasNext()) {
                indexingId1.setFilterTag(iterator1.next());
                Indexing occupiedIndexing = this.indexingService.getIndexing(indexingId1);
                if (null != occupiedIndexing && (!brdRequirement.getReqId().equalsIgnoreCase(occupiedIndexing.getIndexMap().keySet().iterator().next()))) {
                    executeResult.setCode(BaseController.REQUEST_ERROR);
                    executeResult.setDesc("feature occupied by other req, reqId:" + occupiedIndexing.getIndexMap().keySet().iterator().next());
                    return executeResult;
                }
            }
        }
        if (!CollectionUtils.isEmpty(newMap)) {
            //先更新req_feature_indexing
            indexing.setIndexMap(newMap);
            try {
                this.indexingService.indexing(indexing);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                executeResult.setCode(BaseController.REQUEST_ERROR);
                executeResult.setDesc(e.getMessage());
                return executeResult;
            }

        }

        //生成removeMap
        if (!CollectionUtils.isEmpty(existsMap)) {
            removeIndexMap.putAll(existsMap);
            if (!CollectionUtils.isEmpty(newMap)) {
                removeIndexMap.keySet().removeAll(newMap.keySet());
            }
        }


        //处理新增
        if (!CollectionUtils.isEmpty(addIndexingMap)) {
            Indexing indexing1 = new Indexing();
            indexing1.setId(indexingId1);
            Iterator<String> iterator = addIndexingMap.keySet().iterator();
            while (iterator.hasNext()) {
                Map<String, String> temp = new HashMap<>();
                indexingId1.setFilterTag(iterator.next());
                temp.put(brdRequirement.getReqId(), brdRequirement.getReqId());
                indexing1.setIndexMap(temp);
                try {
                    this.indexingService.indexing(indexing1);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    executeResult.setCode(BaseController.REQUEST_ERROR);
                    executeResult.setDesc(e.getMessage());
                    return executeResult;
                }
            }
        }

        //处理删除
        if (!CollectionUtils.isEmpty(removeIndexMap)) {
            Set<String> featuresIds = removeIndexMap.keySet();
            int size = featuresIds.size();
            String[] ids = new String[size];
            Iterator<String> strs = featuresIds.iterator();
            for (int i = 0; i < size; i++) {
                ids[i] = strs.next();

                //删除功能点描述
//                ReqFeatureId deleteReqFeatureId = new ReqFeatureId();
//                deleteReqFeatureId.setFlowId(ids[i]);
//                deleteReqFeatureId.setReqId(brdRequirement.getReqId());
                this.reqFeatureRepository.deleteById(brdRequirement.getReqId(), ids[i]);

            }
            try {
                this.indexingService.remove(indexingId, ids);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                executeResult.setCode(BaseController.REQUEST_ERROR);
                executeResult.setDesc(e.getMessage());
                return executeResult;
            }
            Iterator<String> iterator = featuresIds.iterator();
            while (iterator.hasNext()) {
                indexingId1.setFilterTag(iterator.next());
                this.indexingService.deleteIndex(indexingId1);
            }
        }


        return executeResult;
    }


    private ExecuteResult<BrdRequirement> deleteBrdRequirement(BrdRequirement brdRequirement) {
        ExecuteResult<BrdRequirement> rs = new ExecuteResult<BrdRequirement>();
        if (!this.brdRequirementCanDelete(brdRequirement.getReqId(), rs)) {
            return rs;
        }
        BrdRequirement dbBrdRequirement = this.brdRequirementRepository.findOne(brdRequirement.getReqId());
        BrdRequirement indexingFlush = new BrdRequirement();
        indexingFlush.setReqId(brdRequirement.getReqId());
        //TODO
        rs = this.flushIndexing(indexingFlush);
        if (!rs.success()) {
            return rs;
        }


        BrdRequirement updates = new BrdRequirement();
        updates.setReqId(brdRequirement.getReqId());
        updates.setReqIsDel(brdRequirement.getReqIsDel());
        if (!StringUtils.isEmpty(dbBrdRequirement.getIssues())) {
            this.refreshIssues(brdRequirement.getReqId(), "");
        }
        rs.setData(brdRequirement);
        return rs;
    }


    /**
     * 判断该reqId指定的brd_requirement能否删除
     *
     * @param reqId
     * @param rs
     * @return
     */
    private boolean brdRequirementCanDelete(String reqId, ExecuteResult<BrdRequirement> rs) {
        BrdRequirement brdExists = this.brdRequirementRepository.findOne(reqId);
        if (brdExists == null) {     //不存在的条目无删除操作
            String msg = "no brd_requirement found for req_id: " + reqId;
            log.error(msg);
            rs.setCode(BaseController.REQUEST_ERROR);
            rs.setDesc(msg);
            return false;
        }
        return this.canBrdRequirementEntityDelete(brdExists, rs);
    }

    /**
     * 判定数据库中的实体是否能够删除
     *
     * @param entity
     * @param rs
     * @return
     */
    public boolean canBrdRequirementEntityDelete(BrdRequirement entity, ExecuteResult rs) {

        if ("0".equals(entity.getReqIsDel())) {   //已经删除的不允许再次执行删除操作
            String msg = "brd_requirement defined has been deleted already. req_id:" + entity.getReqId();
            log.error(msg);
            rs.setCode(BaseController.REQUEST_ERROR);
            rs.setDesc(msg);
            return false;
        }
        if (BrdRequirementStatus.COMPLETED.name().equals(entity.getReqStatus())) {       //已完成的不允许删除
            String msg = "brd_requirement defined has been completed already. req_id:" + entity.getReqId();
            log.error(msg);
            rs.setCode(BaseController.REQUEST_ERROR);
            rs.setDesc(msg);
            return false;
        }

        /**如果关联有PRD未删除，那么该brdRequiement不允许删除 */
        String projectPlanId = entity.getProjectPlanId();
        if (!StringUtils.isEmpty(projectPlanId)) {
            ProjectPlan projectPlan = this.projectPlanService.getUndeletedProjectPlanById(projectPlanId);
            if (null != projectPlan) {
                String msg = "delete cannot be done for exist projectPlan related to this requirement, req_id:" + entity.getReqId() + ". pp_id:" + projectPlan.getProjectPlanId() + ";pp_name:" + projectPlan.getProjectPlanName();
                log.error(msg);
                rs.setCode(BaseController.REQUEST_ERROR);
                rs.setDesc(msg);
                return false;
            }
        }
        return true;
    }

    public ExecuteResult operateForReqOnline(List<String> reqIdLst) {
        ExecuteResult executeResult = null;
        for (String reqId : reqIdLst) {
            executeResult = this.reqOnlineOperation(reqId);
        }
        return executeResult;
    }

    public ExecuteResult reqOnlineOperation(String reqId) {
        ExecuteResult executeResult = new ExecuteResult();
        BrdRequirement brdRequirement = this.brdRequirementRepository.findOne(reqId);
        if (null == brdRequirement) {
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setDesc("cannot found defined req for defined reqId:" + reqId);
            return executeResult;
        }
        if ("0".equalsIgnoreCase(brdRequirement.getReqIsDel())) {
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setDesc("defined req has been deleted for defined reqId:" + reqId);
            return executeResult;
        }
        if (!Status.P_PLAN.name().equalsIgnoreCase(brdRequirement.getReqStatus())) {
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setDesc("cannot publish for reqStatus:" + brdRequirement.getReqStatus() + ". only status of P_PLAN can publish");
            return executeResult;
        }


//        /** 更新prd */
//        ProjectPlan projectPlanUpdate = new ProjectPlan();
//        projectPlanUpdate.setProjectPlanId(brdRequirement.getProjectPlanId());
//        projectPlanUpdate.setProjectPlanStatus(Status.COMPLETED.name());
//        List<BrdRequirement> projectPlanRelatedReqs = this.brdRequirementRepository.findByProjectPlanId(brdRequirement.getProjectPlanId());
//        for (BrdRequirement temp : projectPlanRelatedReqs) {
//            if ((!"0".equalsIgnoreCase(temp.getReqIsDel())) && (!Status.COMPLETED.name().equalsIgnoreCase(temp.getReqStatus())) && (!reqId.equalsIgnoreCase(temp.getReqId()))) {    //存在未删除未完成的req，则为部分上线
//                projectPlanUpdate.setProjectPlanStatus(Status.PARTIAL_COMPLETED.name());
//                break;
//            }
//        }
//        this.projectPlanService.updateProjectPlanById(projectPlanUpdate);

        BrdRequirement reqUpdate = new BrdRequirement();
        reqUpdate.setReqId(reqId);
        reqUpdate.setReqStatus(Status.COMPLETED.name());
        this.requirementRepositoryOperation.updateBrdRequirementById(reqUpdate);

        /** 调用issueService更新issue状态 */
        Map map = new HashMap<>();
        map.put("reqId",reqId);
        msgSend.sendReqMsg(MqMsgType.ONLINE,map);

        this.issueService.operateForReqOnline(reqId);

        /**
         * 调用feature和flow上线
         */
        executeResult = this.flowService.operateForReqOnline(reqId);
        if (!executeResult.success()){
            return executeResult;
        }

        String reqName = brdRequirement.getReqName();
        reqName = reqName == null ? "UNKNOW" : reqName;
        try {
            List<String> reqIdLst = new ArrayList<>();
            reqIdLst.add(reqId);
            ExecuteResult result = featureManager.operateFeaturesForReqOnline(reqIdLst, reqName);
            if (!result.success()){
                executeResult.toError(result.getDesc());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.toError(e.getMessage());
        }

        return executeResult;
    }


    public ExecuteResult operateRelationBetweenReqAndFeature(String featureIds, String reqId, String opMode) {
        ExecuteResult executeResult = new ExecuteResult();
        if (StringUtils.isEmpty(featureIds) || StringUtils.isEmpty(reqId) || StringUtils.isEmpty(opMode)) {
            executeResult.toError("更改feature与req关系时所有参数不能为空");
            return executeResult;
        }
        BrdRequirement brdRequirement = this.brdRequirementRepository.findOne(reqId);
        if (null == brdRequirement) {
            executeResult.toError("指定req的requirement不存在");
            return executeResult;
        }
        String dbFeatureIds = brdRequirement.getFeatures();
        if ("1".equals(opMode)) {
            if (StringUtils.isEmpty(dbFeatureIds)) {
                dbFeatureIds = featureIds;
            } else {
                List<String> dbFeatureIdsLst = Arrays.asList(dbFeatureIds.split(","));
                List<String> featureIdsLst = Arrays.asList(featureIds.split(","));
                for (String featureId : featureIdsLst) {
                    if ((!StringUtils.isEmpty(featureId)) && (!dbFeatureIdsLst.contains(featureId))) {
                        dbFeatureIds = dbFeatureIds + "," + featureId;
                    }
                }
            }
        } else {
            if (StringUtils.isEmpty(dbFeatureIds)) {
                return executeResult;
            }
            String[] ids = dbFeatureIds.split(",");
            List<String> tempIds = new ArrayList<>();
            tempIds.addAll(Arrays.asList(ids));
            String[] removeIds = featureIds.split(",");
            for (String str : removeIds) {
                tempIds.remove(str);
            }
            if (tempIds.size() <= 0) {
                dbFeatureIds = null;
            } else {
                dbFeatureIds = "";
                for (String str : tempIds) {
                    dbFeatureIds = dbFeatureIds + str + ",";
                }
                dbFeatureIds = dbFeatureIds.substring(0, dbFeatureIds.length() - 1);
            }
        }
        this.brdRequirementRepository.updateFeaturesByReqId(reqId, dbFeatureIds);
        return executeResult;
    }


    public String getReqFeatureIds(String reqId) {
        BrdRequirement dbBrdRequirement = this.brdRequirementRepository.findOne(reqId);
        if (null == dbBrdRequirement) {
            return null;
        }
        return dbBrdRequirement.getFeatures();
    }

    public ExecuteResult updateReqFeatureSequence(String reqId, List<String> features) {
        ExecuteResult executeResult = new ExecuteResult();
        if (StringUtils.isEmpty(reqId) || CollectionUtils.isEmpty(features)) {
            executeResult.toError("reqId, features均不能为空");
            return executeResult;
        }
        String featureIds = "";
        for (String id : features) {
            featureIds = featureIds + id + ",";
        }
        featureIds = featureIds.substring(0, featureIds.length() - 1);
        this.brdRequirementRepository.updateFeaturesByReqId(reqId, featureIds);
        return executeResult;
    }



    public ExecuteResult updateReqIssueSequence(String reqId, List<String> issues) {
        ExecuteResult executeResult = new ExecuteResult();
        if (StringUtils.isEmpty(reqId) || CollectionUtils.isEmpty(issues)) {
            executeResult.toError("reqId, issuesIds均不能为空");
            return executeResult;
        }
        String issuesIds = "";
        for (String id : issues) {
            issuesIds = issuesIds + id + ",";
        }
        issuesIds = issuesIds.substring(0, issuesIds.length() - 1);
        this.brdRequirementRepository.updateIssuesByReqId(reqId, issuesIds);
        return executeResult;
    }


    public ExecuteResult submit(String reqId, String tokenId) {
        ExecuteResult executeResult = new ExecuteResult();
        LoginUser user = UserInfoUtil.getUserInfo(tokenId, BEETLE_AUTH_URL);
        if (user == null) {
            log.info("查询用户用户不存在.tokenId=" + tokenId);
            executeResult.toError("token指定的用户不存在");
            return executeResult;
        }
        BrdRequirement brdRequirement = this.brdRequirementRepository.findOne(reqId);
        if (null == brdRequirement){
            executeResult.toError("指定id的req不存在");
            return executeResult;
        }
        ReqHistory reqHistory = new ReqHistory();
        reqHistory.setId(SeqGenerate.createId("RHI"));
        reqHistory.setCreateTime(new Date());
        reqHistory.setReqId(reqId);
        String newVersion = this.getLatestVersionForReq(reqId);
        reqHistory.setVersion(newVersion);
        reqHistory.setCreaterAccount(user.getAccount());
        reqHistory.setCreaterRealname(user.getRealname());
        reqHistory.setFeatures(brdRequirement.getFeatures());
        reqHistory.setFlows(brdRequirement.getFlows());
        this.reqHistoryRepository.save(reqHistory);



        /** 调用submit flow */
        executeResult = this.flowService.reqSubmit(reqId, newVersion);
        if (!executeResult.success()){
            return executeResult;
        }
        /** 开始调用submit feature */
        String reqName = brdRequirement.getReqName();
        reqName = reqName == null ? "UNKNOW" : reqName;
        try {
            ExecuteResult result = featureManager.reqSubmit(reqId, newVersion, reqName);
            if (!result.success()){
                executeResult.toError(result.getDesc());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.toError(e.getMessage());
        }
        return executeResult;
    }

    private String getLatestVersionForReq(String reqId) {
        String version = null;
        ReqHistory newestReqHistory = this.reqHistoryRepository.findFirstByReqIdOrderByCreateTimeDesc(reqId);
        if(null==newestReqHistory) {
            version = "v1.1.1";
        }else{
            version = this.getVersionOfVersionHistoryForReqVersion(newestReqHistory.getVersion());
        }
        return version;
    }
    private String getVersionOfVersionHistoryForReqVersion(String oldVersion){
        if (StringUtils.isEmpty(oldVersion)){
            return "v1.1.1";
        }
        String version = "v";
        oldVersion = oldVersion.substring(1);
        oldVersion = oldVersion.replaceAll("\\.", "");
        Integer intVersion = Integer.valueOf(oldVersion) + 1;
        for (char ch : intVersion.toString().toCharArray()){
            version = version + ch + ".";
        }
        version = version.substring(0, version.length() - 1);
        return version;
    }


    public List getReqSubmitHistory(String reqId) {
        return this.reqHistoryRepository.findByReqIdOrderByCreateTimeAsc(reqId);
    }


    public ReqHistory getLatestReqSubmitHistory(String reqId){
        return this.reqHistoryRepository.findFirstByReqIdOrderByCreateTimeDesc(reqId);
    }

    public List<BrdRequirement> getIssueIdBrdRequirement(String issueId){
        return brdRequirementRepository.getIssueIdBrdRequirement(issueId);
    }

    public ExecuteResult saveBrdRequirementGuideMap(String reqId, JSONObject jsonObject){
        ExecuteResult executeResult = new ExecuteResult();
        BrdRequirement brdRequirement=brdRequirementRepository.findOne(reqId);
        if(null==brdRequirement){
            executeResult.toError("reqId, issuesIds均不能为空");
            return executeResult;
        }

        Config config = new Config();
        if(!StringUtils.isEmpty(brdRequirement.getConfigId())){
            config.setId(brdRequirement.getConfigId());
        }
        Map<String,String> map=new HashMap<>();
        map.put("class", jsonObject.get("class").toString());
        map.put("nodeDataArray", jsonObject.getJSONArray("nodeDataArray").toString());
        config.setKVMap(map);
        config=configService.saveConfig(config);
        brdRequirement.setConfigId(config.getId());
        brdRequirementRepository.save(brdRequirement);
        executeResult.setData(config.getId());

        return executeResult;
    }


    public ExecuteResult getBrdRequirementGuideMap(String reqId){
        ExecuteResult executeResult = new ExecuteResult();
        BrdRequirement brdRequirement=brdRequirementRepository.findOne(reqId);
        if(null==brdRequirement || StringUtils.isEmpty(brdRequirement.getConfigId())){
            return executeResult;
        }
        Config config = null;
        try {
            config = configService.getConfigMap(brdRequirement.getConfigId(), false);
        } catch (Exception e) {
            executeResult.toError("查询导图异常");
        }
        if(config!=null){
            executeResult.setData(config.getKVMap());
        }

        return executeResult;
    }
}
